﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using System.Net;
using Umbrella.Net.Contracts;

namespace Umbrella.Whs.WhsAddin.ConsoleControls
{
    public partial class UpdateAvailable : ConsoleControlBase
    {
        private UmbrellaReleaseInfo _releaseInfo;
        private readonly FileInfo _installerMsi = new FileInfo(Whs.Properties.Constants.UmbrellaMsiPath);

        public UpdateAvailable(UmbrellaConsoleTab tab)
            : base(tab)
        {
            if (_log.IsDebugEnabled)
                _log.Debug("Initialization start");

            try
            {
                InitializeComponent();
	
                this.lineBox.Header.Text = Properties.Resources.txtUpdateAvailable;

                // done
                if (_log.IsDebugEnabled)
                    _log.Debug("Initialization done");
            }
            catch (Exception e)
            {
                _log.Fatal("Failed to initialize", e);

                throw;
            }
        }

        private void downloadLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            StartDownloading();
        }

        private void UpdateAvailable_Load(object sender, EventArgs e)
        {
            if (_log.IsDebugEnabled)
                _log.Debug("Loading start");

            try
            {
                // query release info
                {
                    var ri = _singletonService.Channel.GetNewerVersion();

                    if (ri == null)
                        throw new Exception("no update");

                    _releaseInfo = ri;
                }

                // set label
                this.versionLbl.Text = string.Format(
                    Properties.Resources.txtUpdateUmbrellaTitle,
                    _releaseInfo.VersionString
                    );

                this.releaseInfoLinkLabel.Enabled = !string.IsNullOrEmpty(_releaseInfo.ReleaseUrl);
                this.downloadLinkLabel.Enabled = !string.IsNullOrEmpty(_releaseInfo.MsiDownloadUrl);

                // done
                if (_log.IsDebugEnabled)
                    _log.Debug("Loading done");
            }
            catch (Exception x)
            {
                _log.Fatal("Loading failed", x);

                throw;
            }
        }

        private void homepageLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            _tab.Services.OpenUrl(Whs.Properties.Constants.HomepageUrl);
        }

        private void releaseInfoLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            _tab.Services.OpenUrl(_releaseInfo.ReleaseUrl);
        }

        private void downloadBgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                // cleanup existing file
                _installerMsi.Refresh();

                if (_installerMsi.Exists)
                    _installerMsi.Delete();

                // download
                using (var wc = new WebClient())
                {
                    wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(downloadWebClient_DownloadProgressChanged);

                    // start download
                    wc.DownloadFileAsync(
                        new Uri(_releaseInfo.MsiDownloadUrl),
                        _installerMsi.FullName
                        );

                    // wait for download
                    while (wc.IsBusy)
                    {
                        System.Threading.Thread.Sleep(100);

                        if (e.Cancel)
                        {
                            wc.CancelAsync();

                            break;
                        }
                    }
                }

            }
            catch (Exception x)
            {
                _log.Error("Failed to download installer from " + _releaseInfo.MsiDownloadUrl, x);

                Microsoft.HomeServer.Controls.QMessageBox.Show(
                    x.Message,
                    Properties.Resources.txtUpdateDownloadFailed,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                    );
            }
        }

        private void downloadWebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            this.downloadBgWorker.ReportProgress(e.ProgressPercentage);
        }

        private void downloadBgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.filledBar.Percentage = e.ProgressPercentage;
        }

        private void downloadBgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _installerMsi.Refresh();

            // delete incomplete download
            if (e.Cancelled)
            {
                if (_installerMsi.Exists)
                    _installerMsi.Delete();

                _installerMsi.Refresh();
            }

            // reset gui
            this.downloadLinkLabel.Enabled = !_installerMsi.Exists;
            this.cancelDownloadLinkLabel.Visible = false;
            this.filledBar.Percentage = 100;
        }

        private void StartDownloading()
        {
            this.downloadLinkLabel.Enabled = false;
            this.cancelDownloadLinkLabel.Enabled = true;
            this.cancelDownloadLinkLabel.Visible = true;
            this.filledBar.Percentage = 0;

            this.downloadBgWorker.RunWorkerAsync();
        }

        private void cancelDownloadLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this.downloadBgWorker.CancelAsync();

            this.cancelDownloadLinkLabel.Enabled = false;
        }

        private void openAddinsLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            _tab.Services.OpenSettings(new Guid(Whs.Properties.Constants.AddinsSettingsTabGuid));
        }

        private void returnLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            _tab.ResetState();
        }
    }
}


